package com.allenkerr.dao.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.FindAndModifyOptions;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;

import com.allenkerr.common.SequenceException;
import com.allenkerr.dao.SequenceRepository;
import com.allenkerr.dao.SequenceRepositoryCustom;
import com.allenkerr.model.Sequence;

/**
 * Created by 小柯 on 17/8/25.
 */
public class SequenceRepositoryImpl implements SequenceRepositoryCustom {

    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private SequenceRepository sequenceDao;

    private static final long INITIAL_VALUE = 1L;

    @Override
    public long getNextSequence(String collectionName) {
        boolean isExisted = sequenceDao.exists(collectionName);
        if (!isExisted) {
            Sequence sequenceToSave = new Sequence(collectionName, INITIAL_VALUE);
            sequenceDao.save(sequenceToSave);
            return sequenceToSave.getSeq();
        }

        //QUERY
        Query query = Query.query(Criteria.where("_id").is(collectionName));
        //UPDATE
        Update update = new Update().inc("seq", 1);
        //OPTIONS
        FindAndModifyOptions options = FindAndModifyOptions.options().returnNew(true);

        Sequence sequence = mongoTemplate.findAndModify(query, update, options, Sequence.class);

        //throws SequenceException to tell user when the sequence id is failed to generate.
        if (sequence == null) {
            throw new SequenceException("Unable to get next sequence id for key : " + collectionName);
        }

        return sequence.getSeq();
    }

}
